﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TweetSharp.Twitter.Extensions;
using TweetSharp.Twitter.Fluent;
using TweetSharp.Twitter.Model;
using System.Deployment.Application;
using TweetSharp;

namespace Halfwit
{
    public static class TwitterConnection
    {
        static TwitterConnection()
        {
            FollowerIds = new List<long>();
            FriendIds = new List<long>();
            RecentUserNames = new List<string>();

            _clientInfo = new TwitterClientInfo
            {
                ClientName = "Halfwit",
                ClientUrl = "http://madprops.org",
                ConsumerKey = Properties.Settings.Default.ConsumerKey,
                ConsumerSecret = Properties.Settings.Default.ConsumerSecret,
            };

            if (ApplicationDeployment.IsNetworkDeployed)
            {
                _clientInfo.ClientVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString();
            }

            FluentTwitter.SetClientInfo(_clientInfo);
        }

        private static TwitterClientInfo _clientInfo;

        public static IFluentTwitter CreateRequest()
        {
            return FluentTwitter
                .CreateRequest()
                .AuthenticateWith(
                    Properties.Settings.Default.AccessToken,
                    Properties.Settings.Default.AccessTokenSecret);
        }

        public static bool Authenticate()
        {
            if (String.IsNullOrEmpty(Properties.Settings.Default.AccessToken) ||
                String.IsNullOrEmpty(Properties.Settings.Default.AccessTokenSecret))
            {
                return false;
            }

            // check that the stored authentication is valid
            var twitter = CreateRequest().Account().VerifyCredentials();
            try
            {
                var response = twitter.Request();
                if (response.IsTwitterError || response.IsNetworkError || response.IsFailWhale)
                {
                    return false;
                }

                var bogus = new System.Text.RegularExpressions.Regex("\"user\"\\:\\{\"id\"\\:\\d+\\}\\,");
                response.Response = bogus.Replace(response.Response, string.Empty);

                User = response.AsUser();
                if (User == null) return false;

                UpdateFollowers();
                GetFriends();

                return true;
            }
            catch 
            {
                return false;
            }
        }

        private static void GetFriends()
        {
            var friends = CreateRequest()
                //.Users().GetFriends().CreateCursor().Request();
                .SocialGraph()
                .Ids().ForFriends().CreateCursor().Request();

            while (!(friends.IsNetworkError || friends.IsTwitterError || friends.IsFailWhale))
            {
                FriendIds.AddRange(friends.AsIds());
                //var users = friends.AsUsers();
                //if (users == null) return;

                //FriendIds.AddRange(users.Select(u => (long)u.Id));
                //if (RecentUserNames.Count < 1000)
                //    RecentUserNames.AddRange(users.Select(u => u.ScreenName));

                var nextCursor = friends.AsNextCursor();

                if ((nextCursor ?? 0) == 0) break;

                friends = CreateRequest()
                    //.Users().GetFriends().GetCursor(nextCursor.Value).Request();
                    .SocialGraph()
                    .Ids().ForFriends()
                    .GetCursor(nextCursor.Value).Request();
            }
        }

        public static void AddRecentUserNames(IEnumerable<String> userNames)
        {
            RecentUserNames.RemoveAll(n => userNames.Any(u => String.Compare(u, n, StringComparison.OrdinalIgnoreCase) == 0));

            RecentUserNames.AddRange(userNames);

            if (RecentUserNames.Count > 1000)
            {
                // ditch the first user names
                RecentUserNames.RemoveRange(0, RecentUserNames.Count - 1000);
            }
        }

        public static void UpdateFollowers()
        {
            var followers = CreateRequest()
                .SocialGraph()
                .Ids().ForFollowers().CreateCursor().Request();

            while (!(followers.IsNetworkError || followers.IsTwitterError || followers.IsFailWhale))
            {
                FollowerIds.AddRange(followers.AsIds().Where(i => !FollowerIds.Contains(i)));

                var nextCursor = followers.AsNextCursor();

                if ((nextCursor ?? 0) == 0) break;

                followers = CreateRequest()
                    .SocialGraph()
                    .Ids().ForFollowers()
                    .GetCursor(nextCursor.Value).Request();
            }
        }

        public static TwitterUser User { get; private set; }
        public static List<long> FollowerIds { get; private set; }
        public static List<long> FriendIds { get; private set; }
        public static List<string> RecentUserNames { get; private set; }

        public static int UserId
        {

            get { return User == null ? 0 : User.Id; }
        }

        //public static void RequestAsyncSafe(this ITwitterLeafNode request, TwitterWebCallback Callback)
        //{
        //    System.Threading.ThreadPool.QueueUserWorkItem(o =>
        //     {
        //         try
        //         {
        //             var req = (ITwitterLeafNode)o;
        //             var result = req.Request();
        //             if (Callback != null)
        //             {
        //                 Callback(req, result, null);
        //             }
        //         }
        //         catch
        //         {
        //         }
        //     }, request);
        //}
    }
}
